﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using VisionConfig;

namespace FalionForm.ComAdd
{
    /// <summary>
    /// ComAdd_1.xaml 的交互逻辑
    /// </summary>
    public partial class ComAdd_1 : Page
    {
        public HalconWindowProcess Vis3D = new HalconWindowProcess();
        HObject Region_X = new HObject();
        HObject Region_Y = new HObject();
        HObject Region_Z = new HObject();
        Chart chartx = new Chart();
        Chart charty = new Chart();
        Chart chartz = new Chart();
        public Thread tdisplay;
        HTuple hv_ModelObjectModel3D = new HTuple();
        HTuple Model3DDisp = new HTuple();
        VisionTool VT = new VisionTool();
        HTuple ToolOrigin, ToolBase; //两种工具模型
        HTuple TranTool;//转换后的工具模型
        HTuple ObjectAndTool=new HTuple(); //包含工具的模型
        bool DispTranTool = false;


        public void Clear()
        {

            if (tdisplay != null && tdisplay.IsAlive)
            {
                Vis3D.bBreak = true;
                Thread.Sleep(10);
                tdisplay.Join();
                tdisplay.Abort();
                Thread.Sleep(20);
            }
        }
        public ComAdd_1()
        {
            InitializeComponent();
            HOperatorSet.GenEmptyObj(out Region_X);
            HOperatorSet.GenEmptyObj(out Region_Y);
            HOperatorSet.GenEmptyObj(out Region_Z);
            HOperatorSet.GenEmptyObj(out Page3.Region_all);
            chart_x.Child = chartx;
            chart_y.Child = charty;
            chart_z.Child = chartz;
            //Intiali();
            this.dataGrid.BeginInit();
            this.dataGrid.ItemsSource = PublicData.Clist;
            this.dataGrid.EndInit();
            UpdataList();//更新标定列表
            VT.gen_tool_3d(0.5, 5,out ToolOrigin,out ToolBase);//生成模型
        }


        private void Intiali()//数据初始化
        {
            slider_x.EndValue = PublicData.infoIntiza.Xmax;
            slider_x.StartValue = PublicData.infoIntiza.Xmin;
            slider_y.EndValue = PublicData.infoIntiza.Ymax;
            slider_y.StartValue = PublicData.infoIntiza.Ymin;
            slider_z.EndValue = PublicData.infoIntiza.Zmax;
            slider_z.StartValue = PublicData.infoIntiza.Zmin;
        }
        //显示画面
        public void Display()
        {
            Page3._dp.DramModel = true;
            HOperatorSet.SetLut(Page3._dp.HW, "default");
            HTuple hv_PoseOut;
            if (DispTranTool)
            {
                HOperatorSet.ClearObjectModel3d(ObjectAndTool);
                HOperatorSet.CopyObjectModel3d(Model3DDisp, "all", out ObjectAndTool);

               // ObjectAndTool.TupleConcat(TranTool);
                ObjectAndTool.Append(TranTool);

                DispTranTool = false;
                Vis3D.visualize_object_model_3d(Page3._dp.HW, ObjectAndTool, new HTuple(), new HTuple(), "colored", 12,  out hv_PoseOut);
                
            }
            else
            {
                Vis3D.visualize_object_model_3d(Page3._dp.HW, Model3DDisp, new HTuple(), new HTuple(), "color", "green",out hv_PoseOut);
            }
        }

        //滑动条
        bool xisrun = false;
        bool yisrun = false;
        bool zisrun = false;
        int sx_s, sx_e, sy_s, sy_e, sz_s, sz_e;
        private void change_x(int m)//滑动条事件
        {
            if (xisrun)
            {
                return;
            }
            if (Page3.ho_X.IsInitialized())
            {
                xisrun = true;
                ab();
                ThreadPool.QueueUserWorkItem(new WaitCallback(abc), new object());    //参数可选
            }

        }
        bool f = false;
        private void ab()
        {
            sx_s = slider_x.StartValue;
            sx_e = slider_x.EndValue;
            if (sx_s == sx_e)
            {
                sx_e++;
            }
            sy_s = slider_y.StartValue;
            sy_e = slider_y.EndValue;
            if (sy_s == sy_e)
            {
                sy_e++;
            }
            sz_s = slider_z.StartValue;
            sz_e = slider_z.EndValue;
            if (sz_s == sz_e)
            {
                sz_e++;
            }
            if (!f)
            {
                try
                {
                    HOperatorSet.Threshold(Page3.ho_Z, out Region_Z, sz_s, sz_e);
                    HOperatorSet.Threshold(Page3.ho_Y, out Region_Y, sy_s, sy_e);
                    HOperatorSet.Threshold(Page3.ho_X, out Region_X, sx_s, sx_e);
                    f = true;
                }
                catch { }
            }
        }
        private void abc(object ob)
        {

            try
            {
                Region_X.Dispose();
                HOperatorSet.Threshold(Page3.ho_X, out Region_X, sx_s, sx_e);
            }
            catch
            {
            }
            GetAllRegion();
            Page3._dp.DispImage(Page3.ho_Z);
            xisrun = false;
        }
        private void change_y(int m)//滑动条事件
        {
            if (yisrun)
            {
                return;
            }
            if (Page3.ho_Y.IsInitialized())
            {
                yisrun = true;
                ab();
                ThreadPool.QueueUserWorkItem(new WaitCallback(abd), new object());    //参数可选
            }
        }
        private void abd(object obj)
        {
            try
            {
                Region_Y.Dispose();
                HOperatorSet.Threshold(Page3.ho_Y, out Region_Y, sy_s, sy_e);
            }
            catch
            {
            }

            GetAllRegion();
            Page3._dp.DispImage(Page3.ho_Z);
            yisrun = false;
        }
        private void change_z(int m)//滑动条事件
        {
            if (zisrun)
            {
                return;
            }
            if (Page3.ho_Z.IsInitialized())
            {
                zisrun = true;
                ab();
                ThreadPool.QueueUserWorkItem(new WaitCallback(abe), new object());    //参数可选
            }
        }
        private void abe(object obj)
        {
            try
            {
                Region_Z.Dispose();
                HOperatorSet.Threshold(Page3.ho_Z, out Region_Z, sz_s, sz_e);
            }
            catch
            {
            }

            GetAllRegion();
            Page3._dp.DispImage(Page3.ho_Z);
            zisrun = false;
        }
        private void GetAllRegion()//合并区域
        {
            try
            {

                Page3.Region_all.Dispose();
                Page3.Region_all = Region_X.Clone();
                HOperatorSet.Intersection(Region_Y, Page3.Region_all, out Page3.Region_all);
                HOperatorSet.Intersection(Region_Z, Page3.Region_all, out Page3.Region_all);
            }
            catch
            {
                HOperatorSet.Threshold(Page3.ho_Z, out Region_Z, sz_s, sz_e);
                HOperatorSet.Threshold(Page3.ho_Y, out Region_Y, sy_s, sy_e);
                HOperatorSet.Threshold(Page3.ho_X, out Region_X, sx_s, sx_e);
            }

        }


        private void ComboBox_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)//列表切换事件
        {

        }
        public void intize(object obj)//显示数据初始化
        {
            if (!(Page3.ho_X.IsInitialized() && Page3.ho_Y.IsInitialized() && Page3.ho_Z.IsInitialized()))
            {
                return;
            }
            try
            {
                HTuple hv_AbsoluteHisto, hv_RelativeHisto, a, b, c;
                HObject ho_Regionx, ho_Regiony, ho_Regionz;
                HOperatorSet.GenEmptyObj(out ho_Regionx);
                HOperatorSet.GenEmptyObj(out ho_Regiony);
                HOperatorSet.GenEmptyObj(out ho_Regionz);
                HTuple w, h, q, y;
                HOperatorSet.GrayHisto(Page3.ho_X, Page3.ho_X, out hv_AbsoluteHisto, out hv_RelativeHisto);
                HOperatorSet.GenRegionHisto(out ho_Regionx, hv_AbsoluteHisto, 0, 0, 1);
                HOperatorSet.SmallestRectangle1(ho_Regionx, out w, out h, out q, out y);
                HOperatorSet.SetPart(chartx.CaliWindow.HalconWindow, w, h, q, y);
                chartx.CaliWindow.HalconWindow.SetColor("red");

                HOperatorSet.MinMaxGray(Page3.ho_X, Page3.ho_X, 0, out a, out b, out c);


                this.Dispatcher.Invoke(new Action(() =>
                {
                    slider_x.Minimum = (int)a.D;
                    slider_x.Maximum = (int)b.D;

                }));


                HOperatorSet.GrayHisto(Page3.ho_Y, Page3.ho_Y, out hv_AbsoluteHisto, out hv_RelativeHisto);
                HOperatorSet.GenRegionHisto(out ho_Regiony, hv_AbsoluteHisto, 0, 0, 1);
                HOperatorSet.SmallestRectangle1(ho_Regiony, out w, out h, out q, out y);
                HOperatorSet.SetPart(charty.CaliWindow.HalconWindow, w, h, q, y);
                charty.CaliWindow.HalconWindow.SetColor("red");

                HOperatorSet.MinMaxGray(Page3.ho_Y, Page3.ho_Y, 0, out a, out b, out c);


                this.Dispatcher.Invoke(new Action(() =>
                {
                    slider_y.Minimum = (int)a.D;
                    slider_y.Maximum = (int)b.D;

                }));


                HOperatorSet.GrayHisto(Page3.ho_Z, Page3.ho_Z, out hv_AbsoluteHisto, out hv_RelativeHisto);
                HOperatorSet.GenRegionHisto(out ho_Regionz, hv_AbsoluteHisto, 0, 0, 1);
                HOperatorSet.SmallestRectangle1(ho_Regionz, out w, out h, out q, out y);
                HOperatorSet.SetPart(chartz.CaliWindow.HalconWindow, w, h, q, y);
                chartz.CaliWindow.HalconWindow.SetColor("red");

                HOperatorSet.MinMaxGray(Page3.ho_Z, Page3.ho_Z, 0, out a, out b, out c);

                this.Dispatcher.Invoke(new Action(() =>
                {
                    slider_z.Minimum = (int)a.D;
                    slider_z.Maximum = (int)b.D;
                    HOperatorSet.DispRegion(ho_Regionx, chartx.CaliWindow.HalconWindow);
                    HOperatorSet.DispRegion(ho_Regiony, charty.CaliWindow.HalconWindow);
                    HOperatorSet.DispRegion(ho_Regionz, chartz.CaliWindow.HalconWindow);
                }));


                ho_Regionx.Dispose();
                ho_Regiony.Dispose();
                ho_Regionz.Dispose();
            }
            catch
            {

            }

        }
        private void Btn_ResetData(object sender, RoutedEventArgs e)//重置数据
        {
            ThreadPool.QueueUserWorkItem(new WaitCallback(intize), new object());    //参数可选
        }
        private void win_Loaded(object sender, RoutedEventArgs e)//界面载入
        {

        }



        private string GenSaveName()//获取保存路径
        {
            string des;
            if (ChooseNum.SelectedValue.ToString() == "新建标定")
            {
                #region
                int i = 1;
                while (true)
                {
                    bool bl = false;
                    for (int t = 0; t < PublicData.Clist.Count; t++)
                    {
                        if (PublicData.Clist[t].Number == i)
                        {
                            bl = true;
                        }
                    }
                    if (bl == false)
                    {
                        PublicData.Clist.Add(new CalibList { Number = i, Description = "添加描述" });
                        des = i.ToString();
                        //PlugGuide.Strem.save();//保存
                        UpdataList();
                        break;
                    }
                    i++;
                }
                #endregion
            }
            else
            {
                des = ChooseNum.SelectedValue.ToString();
            }
            return des;
        }
        private void UpdataList()//更新标定列表
        {
            string[] str = new string[PublicData.Clist.Count + 1];
            for (int i = 0; i < PublicData.Clist.Count; i++)
            {
                str[i] = PublicData.Clist[i].Number.ToString();
            }
            str[PublicData.Clist.Count] = "新建标定";
            ChooseNum.ItemsSource = str;
            ChooseNum.SelectedIndex = 0;
        }










        //保存新图片
        private void Btn_SaveNewImg(object sender, RoutedEventArgs e)
        {
            if (!(Page3.ho_X.IsInitialized() && Page3.ho_Y.IsInitialized() && Page3.ho_Z.IsInitialized()&& Page3.Region_all != null && Page3.Region_all.IsInitialized()))
            {
                return;
            }

            HObject x, y, z;
            HOperatorSet.ReduceDomain(Page3.ho_X, Page3.Region_all, out x);
            HOperatorSet.ReduceDomain(Page3.ho_Y, Page3.Region_all, out y);
            HOperatorSet.ReduceDomain(Page3.ho_Z, Page3.Region_all, out z);
            HTuple ObjectModel3DID = new HTuple();
            HOperatorSet.XyzToObjectModel3d(x, y, z, out ObjectModel3DID);
            HOperatorSet.ObjectModel3dToXyz(out x, out y, out z, ObjectModel3DID, "from_xyz_map", new HTuple(), new HTuple());
            HOperatorSet.ClearObjectModel3d(ObjectModel3DID);

            HOperatorSet.WriteImage(x, "tiff", 0, "./" + "PicturesModel" + "/Ca_ho_X");
            HOperatorSet.WriteImage(y, "tiff", 0, "./" + "PicturesModel" + "/Ca_ho_Y");
            HOperatorSet.WriteImage(z, "tiff", 0, "./" + "PicturesModel" + "/Ca_ho_Z");
            Page3.ho_X = x.Clone();
            Page3.ho_Y = y.Clone();
            Page3.ho_Z = z.Clone();
            x.Dispose();
            y.Dispose();
            z.Dispose();

        }

        private void Btn_DrawModel(object sender, RoutedEventArgs e)
        {
            if (!(Page3.ho_X.IsInitialized() && Page3.ho_Y.IsInitialized() && Page3.ho_Z.IsInitialized()))
            {
                return;
            }
            //清空模型
            HTuple PiontStatus = new HTuple();
            HOperatorSet.GetObjectModel3dParams(hv_ModelObjectModel3D, "has_points", out PiontStatus);
            if (PiontStatus.Length!=0&&PiontStatus == "true")
            {
                HOperatorSet.ClearObjectModel3d(hv_ModelObjectModel3D);               
            }

            HTuple tmpModel;
            HTuple hv_ModelRows = new HTuple(), hv_ModelColumns = new HTuple();
            HTuple hv_ModelX = new HTuple(), hv_ModelY = new HTuple();
            HTuple hv_ModelZ = new HTuple();   

            HObject ModelRegion = new HObject();
            HOperatorSet.DrawRegion(out ModelRegion, Page3._dp.HW);
            HObject xa, ya, za;
            HOperatorSet.ReduceDomain(Page3.ho_X, ModelRegion,out xa);
            HOperatorSet.ReduceDomain(Page3.ho_Y, ModelRegion, out ya);
            HOperatorSet.ReduceDomain(Page3.ho_Z, ModelRegion, out za);
            HOperatorSet.XyzToObjectModel3d(xa,ya,za,out tmpModel);
            //将阈值应用于3D对象模型的属性

            //以距离分割点云
            HOperatorSet.ConnectionObjectModel3d(tmpModel,"distance_3d", PublicData.infoIntiza.SobelMaxTheshold, out tmpModel);

            //剔除稀疏点
            // HOperatorSet.SelectPointsObjectModel3d(tmpModel, new HTuple("num_neighbors_fast ") + 3, 70, 100000, out tmpModel);

            //筛选点云
            HOperatorSet.SelectObjectModel3d(tmpModel, "num_points", "and", 1000, 1e30, out hv_ModelObjectModel3D);

            xa.Dispose();
            ya.Dispose();
            za.Dispose();
            

            //聚合点云
            HOperatorSet.UnionObjectModel3d(hv_ModelObjectModel3D, "points_surface",out Model3DDisp);

            HOperatorSet.SmoothObjectModel3d(Model3DDisp, "mls",new HTuple(),new HTuple(),out Model3DDisp);

            //计算三角面
            //HTuple Info;
            //HOperatorSet.TriangulateObjectModel3d(Model3DDisp, "greedy", new HTuple(), new HTuple(), out Model3DDisp, out Info);

            //三角面简化 值越小 细节越少
            //HOperatorSet.SimplifyObjectModel3d(Model3DDisp, "preserve_point_coordinates", 2, "amount_type", "percentage_remaining", out Model3DDisp);


            //三角面获取稀疏点云
            //HOperatorSet.SampleObjectModel3d(Model3DDisp, "accurate", PublicData.infoIntiza.SobelMaxTheshold, new HTuple(), new HTuple(), out Model3DDisp);


            if (tdisplay != null && tdisplay.IsAlive)
            {
                Vis3D.bBreak = true;
                Thread.Sleep(10);
                tdisplay.Join();
                tdisplay.Abort();
                Thread.Sleep(20);
            }
            Vis3D.bBreak = false;
            tdisplay = new System.Threading.Thread(new ThreadStart(Display));
            tdisplay.IsBackground = true;
            tdisplay.Start();


            //HOperatorSet.SurfaceNormalsObjectModel3d(hv_ModelObjectModel3D, "mls", "mls_force_inwards", "true", out hv_ModelObjectModel3D);
            ////创建模板
            //HOperatorSet.CreateSurfaceModel(hv_ModelObjectModel3D, 0.02, "model_invert_normals",
            //    "true", out hv_SurfaceModelID);
        }

        private void Btn_DispModel(object sender, RoutedEventArgs e)
        {           
            if (ChooseNum.SelectedValue.ToString().Length==1)
            {
                Model3DDisp = UseData.Model3DDisp[Convert.ToInt32(ChooseNum.SelectedValue.ToString())].Clone();
                HTuple Pose=new HTuple();
                for (int i = 0; i < PublicData.Clist.Count; i++)
                {
                    if (PublicData.Clist[i].Number == Convert.ToInt32(ChooseNum.SelectedValue.ToString()))
                    {
                        Pose = new HTuple(PublicData.Clist[i].X, PublicData.Clist[i].Y, PublicData.Clist[i].Z, PublicData.Clist[i].g, PublicData.Clist[i].b, PublicData.Clist[i].a,0);
                        break;
                    }
                }                
                HOperatorSet.RigidTransObjectModel3d(ToolBase, Pose, out TranTool);
                DispTranTool = true;
            }
            else
            {
                return;
            }
            if (tdisplay != null && tdisplay.IsAlive)
            {
                Vis3D.bBreak = true;
                Thread.Sleep(10);
                tdisplay.Join();
                tdisplay.Abort();
            }
            Vis3D.bBreak = false;
            tdisplay = new System.Threading.Thread(new ThreadStart(Display));
            tdisplay.IsBackground = true;
            tdisplay.Start();


        }

        private void Btn_SaveModel(object sender, RoutedEventArgs e)
        {
            if (Model3DDisp.Length==0)
            {
                return;
            }
            string Path = GenSaveName();


            //计算法向量
            HOperatorSet.SurfaceNormalsObjectModel3d(Model3DDisp, "mls", "mls_force_inwards", "true", out Model3DDisp);


            //创建模板  //数值较大时并不理想  减小数值 增大采样
            HOperatorSet.CreateSurfaceModel(Model3DDisp, 0.03, "model_invert_normals",
                "false", out UseData.Model3D[Convert.ToInt32(Path)]);



            //train_3d_edges //创建三角面模型    model_invert_normals //法线取反         
            HOperatorSet.WriteSurfaceModel(UseData.Model3D[Convert.ToInt32(Path)], "./3DModel/" + Path + ".SFM");
            HOperatorSet.WriteObjectModel3d(Model3DDisp, "obj", "./3DModel/" + Path + ".obj",
                new HTuple(), new HTuple());
            HOperatorSet.CopyObjectModel3d(Model3DDisp,"all",out UseData.Model3DDisp[Convert.ToInt32(Path)]);
        }

        private void DeltaItem_Click(object sender, RoutedEventArgs e)//右键删除
        {
            int _Index = dataGrid.SelectedIndex;
            if (_Index != -1 && _Index < PublicData.Clist.Count)
            {
                PublicData.Clist.RemoveAt(_Index);
                //Strem.save();
                UpdataList();
            }
        }

        //列表数据变化
        private void ChooseNum_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
            int d = 0;
        }
    }







}
